﻿// FLMScan
// Container class owning all components of the FLMScan application
// 
// FLMScan - Featured by FabLab Munich

using System;
using log4net;
using log4net.Config;
using System.Collections.Generic;
using FLMScan.Rotator;
using FLMScan.WorldCoordinateReconstruction.Riedmaier;
using FLMScan.Parameters;
using FLMScan.Capture;
using FLMScan.Serial;

namespace FLMScan
{
    class FLMScanInstance : IDisposable
    {
        private bool isDisposed = false;
        private static FLMScanInstance instance;

        private ILog logger;
        private IFLMScanView view;
        private ICapture capture;
        private IStepRotator stepRotator;
        private IFreeRotator freeRotator;
        private FLMScanParameters parameters;
        private FLMScanController controller;
        private IReconstruction reconstruction;
        private FLMScanViewModel viewModel;

        private FLMScanInstance(IFLMScanView view, ICapture capture, IStepRotator stepRotator, IFreeRotator freeRotator, FLMScanParameters parameters, IReconstruction reconstruction, FLMScanViewModel viewModel)
        {
            logger = LogManager.GetLogger(typeof(FLMScanInstance));
            this.view = view;
            this.capture = capture;
            this.stepRotator = stepRotator;
            this.freeRotator = freeRotator;
            this.parameters = parameters;
            this.reconstruction = reconstruction;
            this.viewModel = viewModel;

            logger.Debug("Registering for view notifications");
            view.ViewLoaded += HandleViewLoaded;
            view.ViewClosed += HandleViewClosed;

            controller = new FLMScanController(parameters, this.view, this.capture, this.stepRotator, this.freeRotator, this.reconstruction, this.viewModel);
        }

        internal IFLMScanView IFLMScanView
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        internal ICapture ICapture
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        internal FLMScan.Rotator.IFreeRotator IFreeRotator
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        internal FLMScan.Parameters.FLMScanParameters FLMScanParameters
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        internal FLMScanController FLMScanController
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        internal IReconstruction IReconstruction
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        internal FLMScanViewModel FLMScanViewModel
        {
            get
            {
                throw new System.NotImplementedException();
            }
            set
            {
            }
        }

        public static FLMScanInstance Instance(IFLMScanView view, ICapture capture, IStepRotator stepRotator, IFreeRotator freeRotator, FLMScanParameters parameters, IReconstruction reconstruction, FLMScanViewModel viewModel)
        {
            if (instance == null)
                instance = new FLMScanInstance(view, capture, stepRotator, freeRotator, parameters, reconstruction, viewModel);            

            return instance;
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        private void HandleViewLoaded(object sender, EventArgs e)
        {

        }

        private void HandleViewClosed(object sender, EventArgs e)
        {
            logger.Debug("Deregistering view notifications");

            view.ViewLoaded -= HandleViewLoaded;
            view.ViewClosed -= HandleViewClosed;

            Dispose();
        }

        private void Dispose(bool isDisposing)
        {
            if (isDisposed)
                return;

            if (isDisposing)
            {
                logger.Debug("Disposing FLMScan");

                isDisposed = true;

                controller.Dispose();
                viewModel.Dispose();
                stepRotator.Dispose();
                freeRotator.Dispose();

                RealSerialPort.Instance(parameters.ArduinoSerialPort).Close();                
            }
        }   

    }
}
